#include "Game.h"
#include "IGameState.h"
#include "CTimer.h"
#include "CRender.h"
#include "CObjectFactory.h"
#include "CObjectManager.h"
#include "CIntroState.h"
#include "CInputManager.h"
#include "Utility.h"
#include "CUIManager.h"
#include "CPause.h"
#include "CMainMenu.h"
#include "COptions.h"
#include "CLoading.h"
#include "CHelp.h"
#include "CPlayer.h"
#include "CTutorial.h"
#include "CCutScene.h"
#include "CHighScore.h"
#include "CEndGame.h"
#include "CGameState.h"
#include "CDirectWrite.h"
#include "CCursor.h"
#include "BinaryIO.h"
#include "CScriptManager.h"
#include "CCamera.h"
#include "CSoundEngine.h"
//#include "CScriptingEngine.h"


Game::Game()
{
	m_nFPS = 0;
	m_nFrameCount = 0;
	m_fTimer = 0.0;
	m_nScreenHeight = 0;
	m_nScreenWidth = 0;

	m_bIsGameLoaded = false;
	m_bShowFPS = true;
}


Game::~Game()
{

}


Game* Game::GetInstance()
{
	static Game game;
	return &game;
}

void Game::StartUp(HWND hWnd, HINSTANCE hInstance, int nWidth, int nHeight, bool bWindowed)
{
	m_Hd = hWnd;
	m_nScreenHeight = nHeight;
	m_nScreenWidth = nWidth;

	m_pRender = CRender::GetInstance();
	m_pRender->InitDevice(hWnd);
	CDirectWrite::GetInstance()->InitFonts();
	CCursor::GetInstance()->Init();

	m_pInputManager = CInputManager::GetInstance();
	m_pInputManager->InitDirectinput(hWnd, hInstance, false, false);
	m_pInputManager->AquireAll();

	m_pObjectFactory = CObjectFactory::GetInstance();
	m_pObjectFactory->StartUp();

	m_pObjectManager = CObjectManager::GetInstance();
	m_pObjectManager->StartUp();

	CIntroState::GetInstance()->StartUp();
	ChangeState(CIntroState::GetInstance());

	//CScriptingEngine::GetInstance()->Init();

	CCamera::GetInstance()->Init(m_nScreenWidth, m_nScreenHeight);

	CUIManager::GetInstance()->StartUp();

	timer = CTimer::GetInstance();
	timer->StartUp();

	m_bIsGameLoaded = true;
}


void Game::ShutDown()
{


	CCursor::GetInstance()->ShutDown();

	CIntroState::GetInstance()->ShutDown();

	CUIManager::GetInstance()->ShutDown();
	
	timer->ShutDown();

	CCamera::GetInstance()->ShutDown();
	//CScriptingEngine::GetInstance()->ShutDown();

	m_pObjectManager->ShutDown();
	m_pObjectFactory->ShutDown();

	CDirectWrite::GetInstance()->ShutDown();
	m_pRender->Shutdown();
}


bool Game::Main()
{
	//Update the current delta first
	timer->Update();


	if(!Input(timer->GetDelta()))
	{
		return false;
	}

	Update(timer->GetDelta());

	//only clear back buffer once
	m_pRender->ClearBackBuffer();
	for(unsigned int i = 0; i < m_vGameStates.size(); i++)
	{
		Render(i);
	}
	CCursor::GetInstance()->Render();
	//only present the scene onces
	m_pRender->PresentBackBuffer();

	return true;

}


void Game::PopState()
{
	m_vGameStates.back()->Leave();
	m_vGameStates.pop_back();
}


void Game::PushState(IGameState* pNewState)
{
	m_vGameStates.push_back(pNewState);
	pNewState->Enter();
}


void Game::ClearState()
{
	while(!m_vGameStates.empty())
	{
		PopState();
	}
}


void Game::ChangeState(IGameState* pNewState)
{
	ClearState();
	PushState(pNewState);
}


IGameState* Game::GetCurrentState()
{
	return m_vGameStates.back();
}


bool Game::Input(double delta)
{
	m_pInputManager->UpdateInput();

	m_vGameStates.back()->GetInput();


	if(m_pInputManager->KeyPressedEx(DIK_F9))
	{
		m_bShowFPS = !m_bShowFPS;
	}



	//START INPUT TESTING
	if(m_pInputManager->KeyPressedEx(DIK_1))
	{
		LOG("You pressed the number 1");
	}
	if(m_pInputManager->MouseButtonPressedEx(LEFTMOUSE_BUTTON))
	{
		LOG("You left clicked the mouse");
	}
	/*if(m_pInputManager->KeyPressedEx(DIK_5))
	{
		CScriptingEngine::GetInstance()->Test();
	}*/
	//END  INPUT TESTING

	return true;
}


void Game::Update(double delta)
{
	CCursor::GetInstance()->Update();

	m_vGameStates.back()->Update(delta);
}


void Game::Render(int nState)
{
	m_vGameStates[nState]->Render();


	m_fTimer += CTimer::GetInstance()->GetDelta();
	m_nFrameCount++;

	if(m_fTimer > 1)
	{
		m_nFPS = m_nFrameCount;

		m_nFrameCount = 0;
		m_fTimer = 0;
	}

	char buffer[50];
	sprintf_s(buffer, "FPS: %i", m_nFPS);

	if(m_bShowFPS)
	{
		CDirectWrite::GetInstance()->DrawText(CDirectWrite::GetInstance()->FPS, buffer, 740, 0, D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f));
	}
}